#include "ui.h"
#include "lvgl.h"
#include "esp_log.h"
#include "driver/gpio.h"

void rgb_init()
{
    gpio_reset_pin(GPIO_NUM_40);
    gpio_reset_pin(GPIO_NUM_41);
    gpio_reset_pin(GPIO_NUM_42);
    gpio_set_direction(GPIO_NUM_40, GPIO_MODE_OUTPUT);
    gpio_set_direction(GPIO_NUM_41, GPIO_MODE_OUTPUT);
    gpio_set_direction(GPIO_NUM_42, GPIO_MODE_OUTPUT);
}

static void ta_event_cb(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t * ta = lv_event_get_target(e);
    lv_obj_t * kb = lv_event_get_user_data(e);

    if(code == LV_EVENT_FOCUSED) {
        if(lv_indev_get_type(lv_indev_get_act()) != LV_INDEV_TYPE_KEYPAD) {
            lv_keyboard_set_textarea(kb, ta);
            lv_obj_clear_flag(kb, LV_OBJ_FLAG_HIDDEN);
        }
    }
    else if(code == LV_EVENT_CANCEL) {
        lv_obj_add_flag(kb, LV_OBJ_FLAG_HIDDEN);
        lv_obj_clear_state(ta, LV_STATE_FOCUSED);
        lv_indev_reset(NULL, ta);   /*To forget the last clicked object to make it focusable again*/
    }
}

uint16_t count=0;
lv_obj_t * btn1;
lv_obj_t * btn2;
lv_obj_t * label_num;
lv_obj_t * label_text;

static lv_obj_t * label_tem;
static lv_obj_t * label_hum;

void tem_hum_update(int temp,int hum)
{
    char str[20]={0};

    sprintf(str,"#0000ff Temp: %d\n",temp);
    lv_label_set_text(label_hum,str);

    sprintf(str,"#ff0000 Hum: %d\n",hum);
    lv_label_set_text(label_tem,str);

}

static void event_add(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t *label1=lv_obj_get_child(btn1,0);
    //lv_obj_t *label2=lv_obj_get_child(btn2,0);

    if(code == LV_EVENT_CLICKED) {
        lv_label_set_text_fmt(label_num,"%d",count);
        count++;
    }
    else if(code == LV_EVENT_VALUE_CHANGED) {
        //lv_label_set_text_fmt(label2,"%d",count);
        count--;
    }
}
void lv_example_btn_1(void)
{
    lv_obj_t * label;

    btn1 = lv_btn_create(lv_scr_act());
    lv_obj_add_event_cb(btn1, event_add, LV_EVENT_ALL, NULL);
    lv_obj_align(btn1, LV_ALIGN_CENTER, 0, -40);

    label = lv_label_create(btn1);
    lv_label_set_text(label, "Button");
    lv_obj_center(label);

    // btn2 = lv_btn_create(lv_scr_act());
    // lv_obj_add_event_cb(btn2, event_back, LV_EVENT_ALL, NULL);
    // lv_obj_align(btn2, LV_ALIGN_CENTER, 0, 40);

    // label = lv_label_create(btn2);
    // lv_label_set_text(label, "Toggle");
    // lv_obj_center(label);

    // label_num=lv_obj_create(lv_scr_act());
    // lv_label_set_text(label_num, "0");
    // lv_obj_align(label_num, LV_ALIGN_CENTER, 20, -40);

    // label_text=lv_obj_create(lv_scr_act());
    // lv_label_set_text(label_text, "text");
    // lv_obj_align(label_text, LV_ALIGN_CENTER, 20, 40);

    // lv_obj_t * label1 = lv_label_create(lv_scr_act());
    // lv_label_set_long_mode(label1, LV_LABEL_LONG_WRAP);     /*Break the long lines*/
    // lv_label_set_recolor(label1, true);                      /*Enable re-coloring by commands in the text*/
    // lv_label_set_text(label1, "#0000ff Re-color# #ff00ff words# #ff0000 of a# label, align the lines to the center "
    //                   "and wrap long text automatically.");
    // lv_obj_set_width(label1, 150);  /*Set smaller width to make the lines wrap*/
    // lv_obj_set_style_text_align(label1, LV_TEXT_ALIGN_CENTER, 0);
    // lv_obj_align(label1, LV_ALIGN_CENTER, 0, -40);

    lv_obj_t * label_num = lv_label_create(lv_scr_act());
    //lv_label_set_long_mode(label2, LV_LABEL_LONG_SCROLL_CIRCULAR);     /*Circular scroll*/
    lv_obj_set_width(label_num, 150);
    lv_label_set_text(label_num, "It is a circularly scrolling text. ");
    lv_obj_align(label_num, LV_ALIGN_CENTER, 0, 40);
}
static void event_cb(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t * label = lv_event_get_user_data(e);

    switch(code) {
        case LV_EVENT_PRESSED:
            lv_label_set_text(label, "The last button event:\nLV_EVENT_PRESSED");
            break;
        case LV_EVENT_CLICKED:
            lv_label_set_text(label, "The last button event:\nLV_EVENT_CLICKED");
            break;
        case LV_EVENT_LONG_PRESSED:
            lv_label_set_text(label, "The last button event:\nLV_EVENT_LONG_PRESSED");
            break;
        case LV_EVENT_LONG_PRESSED_REPEAT:
            lv_label_set_text(label, "The last button event:\nLV_EVENT_LONG_PRESSED_REPEAT");
            break;
        default:
            break;
    }
}
static void event_led(lv_event_t * e)
{
    static uint32_t cnt = 1;
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t * label = lv_event_get_user_data(e);

    if((++cnt)%2)
    {
        gpio_set_level(GPIO_NUM_40,1);
        lv_label_set_text(label, "LED is ON");
    }else{
        gpio_set_level(GPIO_NUM_40,0);
        lv_label_set_text(label, "LED is OFF");
    }
    
}
static void event_led_onoff(lv_event_t * e)
{
    static uint32_t cnt = 1;
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t * label = lv_event_get_user_data(e);

    if((++cnt)%2)
    {
        lv_led_on(label);
    }else{
        lv_led_off(label);
    }
    
}
/**
 * Handle multiple events
 */
void lv_example_event_2(void)
{
    lv_obj_t * btn = lv_btn_create(lv_scr_act());
    lv_obj_set_size(btn, 100, 50);
    lv_obj_center(btn);

    lv_obj_t * btn_label = lv_label_create(btn);
    lv_label_set_text(btn_label, "Click me!");
    lv_obj_center(btn_label);

    lv_obj_t * info_label = lv_label_create(lv_scr_act());
    lv_obj_align(info_label, LV_ALIGN_CENTER, 0, 50);
    lv_label_set_text(info_label, "The last button event:\nNone");

    //tem
    label_tem = lv_label_create(lv_scr_act());
    lv_label_set_recolor(label_tem, true);
    lv_obj_align(label_tem, LV_ALIGN_TOP_RIGHT, 0, 10);
    lv_label_set_text(label_tem, "Temp:");

    //hum
    label_hum = lv_label_create(lv_scr_act());
    lv_label_set_recolor(label_hum, true);
    lv_obj_align(label_hum, LV_ALIGN_TOP_LEFT, 0, 10);
    lv_label_set_text(label_hum, "Hum:");

    lv_obj_t * led_label = lv_label_create(lv_scr_act());
    lv_obj_align(led_label, LV_ALIGN_CENTER, 0, -50);
    lv_label_set_text(led_label, "LED is off");

    lv_obj_t * led1  = lv_led_create(lv_scr_act());
    lv_obj_align(led1, LV_ALIGN_CENTER, -90, 0);
    lv_led_off(led1);

    //lv_obj_add_event_cb(btn, event_cb, LV_EVENT_ALL, info_label);
    lv_obj_add_event_cb(btn, event_led, LV_EVENT_CLICKED, led_label);
    lv_obj_add_event_cb(btn, event_led_onoff, LV_EVENT_CLICKED, led1);
}

void lv_ex_chart_1(void)
{
    /*Create a chart*/
    lv_obj_t * chart;
    chart = lv_chart_create(lv_scr_act());
    lv_obj_set_size(chart, 200, 150);
    lv_obj_center(chart);
    lv_chart_set_type(chart, LV_CHART_TYPE_LINE);   /*Show lines and points too*/

    /*Add two data series*/
    lv_chart_series_t * ser1 = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y);
    lv_chart_series_t * ser2 = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_GREEN), LV_CHART_AXIS_SECONDARY_Y);

    /*Set the next points on 'ser1'*/
    lv_chart_set_next_value(chart, ser1, 10);
    lv_chart_set_next_value(chart, ser1, 10);
    lv_chart_set_next_value(chart, ser1, 10);
    lv_chart_set_next_value(chart, ser1, 10);
    lv_chart_set_next_value(chart, ser1, 10);
    lv_chart_set_next_value(chart, ser1, 10);
    lv_chart_set_next_value(chart, ser1, 10);
    lv_chart_set_next_value(chart, ser1, 30);
    lv_chart_set_next_value(chart, ser1, 70);
    lv_chart_set_next_value(chart, ser1, 90);

    /*Directly set points on 'ser2'*/
    ser2->y_points[0] = 90;
    ser2->y_points[1] = 70;
    ser2->y_points[2] = 65;
    ser2->y_points[3] = 65;
    ser2->y_points[4] = 65;
    ser2->y_points[5] = 65;
    ser2->y_points[6] = 65;
    ser2->y_points[7] = 65;
    ser2->y_points[8] = 65;
    ser2->y_points[9] = 65;

    lv_chart_refresh(chart); /*Required after direct set*/
}

static lv_chart_series_t * ser_tem;
static lv_chart_series_t * ser_hum;
static lv_obj_t * chart;
void add_data(int temp,int hum)
{

    lv_chart_set_next_value(chart, ser_tem, temp);
    lv_chart_set_next_value(chart, ser_hum, hum);

    lv_chart_refresh(chart);
}

static void event_cb_show(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t * chart = lv_event_get_target(e);

    if(code == LV_EVENT_VALUE_CHANGED) {
        lv_obj_invalidate(chart);
    }
    if(code == LV_EVENT_REFR_EXT_DRAW_SIZE) {
        lv_coord_t * s = lv_event_get_param(e);
        *s = LV_MAX(*s, 20);
    }
    else if(code == LV_EVENT_DRAW_POST_END) {
        int32_t id = lv_chart_get_pressed_point(chart);
        if(id == LV_CHART_POINT_NONE) return;

        LV_LOG_USER("Selected point %d", (int)id);

        lv_chart_series_t * ser = lv_chart_get_series_next(chart, NULL);
        while(ser) {
            lv_point_t p;
            lv_chart_get_point_pos_by_id(chart, ser, id, &p);

            lv_coord_t * y_array = lv_chart_get_y_array(chart, ser);
            lv_coord_t value = y_array[id];

            char buf[16];
            lv_snprintf(buf, sizeof(buf), LV_SYMBOL_DUMMY"%d", value);

            lv_draw_rect_dsc_t draw_rect_dsc;
            lv_draw_rect_dsc_init(&draw_rect_dsc);
            draw_rect_dsc.bg_color = lv_color_black();
            draw_rect_dsc.bg_opa = LV_OPA_50;
            draw_rect_dsc.radius = 3;
            draw_rect_dsc.bg_img_src = buf;
            draw_rect_dsc.bg_img_recolor = lv_color_white();

            lv_area_t a;
            a.x1 = chart->coords.x1 + p.x - 20;
            a.x2 = chart->coords.x1 + p.x + 20;
            a.y1 = chart->coords.y1 + p.y - 30;
            a.y2 = chart->coords.y1 + p.y - 10;

            lv_draw_ctx_t * draw_ctx = lv_event_get_draw_ctx(e);
            lv_draw_rect(draw_ctx, &draw_rect_dsc, &a);

            ser = lv_chart_get_series_next(chart, ser);
        }
    }
    else if(code == LV_EVENT_RELEASED) {
        lv_obj_invalidate(chart);
    }
}

/**
 * Circular line chart with gap
 */
void show_temp_hum(void)
{
    /*Create a stacked_area_chart.obj*/
    chart = lv_chart_create(lv_scr_act());
    lv_chart_set_update_mode(chart, LV_CHART_UPDATE_MODE_SHIFT);
    lv_obj_set_size(chart, 240, 200);
    lv_obj_center(chart);

    lv_obj_add_event_cb(chart, event_cb_show, LV_EVENT_ALL, NULL);

    //lv_chart_set_type(chart, LV_CHART_TYPE_SCATTER);
    lv_chart_set_axis_tick(chart, LV_CHART_AXIS_PRIMARY_X, 5, 5, 10, 2, true, 20);
    lv_chart_set_axis_tick(chart, LV_CHART_AXIS_PRIMARY_Y, 10, 5, 9, 2, true, 50);

    lv_chart_set_range(chart, LV_CHART_AXIS_PRIMARY_X, 0, 30);
    lv_chart_set_range(chart, LV_CHART_AXIS_PRIMARY_Y, 10, 90);
    lv_chart_set_point_count(chart, 30);

    ser_tem = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y);
    ser_hum = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_BLUE), LV_CHART_AXIS_PRIMARY_Y);
    /*Prefill with data*/
    // uint32_t i;
    // for(i = 0; i < 30; i++) {
    //     lv_chart_set_next_value(chart, ser_tem, LV_CHART_POINT_NONE);
    //     lv_chart_set_next_value(chart, ser_hum, LV_CHART_POINT_NONE);
    // }

    //lv_timer_create(add_data, 300, chart);

}


/*this is a chart ,can show more data*/
static lv_obj_t * chart_more;
lv_chart_series_t * ser_tem_more;
void add_data_to_more(int temp,int hum)
{

    lv_chart_set_next_value(chart_more, ser_tem_more, temp);
    //lv_chart_set_next_value(chart_more, ser_hum, hum);

    lv_chart_refresh(chart_more);
}

static void slider_x_event_cb(lv_event_t * e)
{
    lv_obj_t * obj = lv_event_get_target(e);
    int32_t v = lv_slider_get_value(obj);
    lv_chart_set_zoom_x(chart_more, v);
}

static void slider_y_event_cb(lv_event_t * e)
{
    lv_obj_t * obj = lv_event_get_target(e);
    int32_t v = lv_slider_get_value(obj);
    lv_chart_set_zoom_y(chart_more, v);
}



void show_temp_hum_more(void)
{
    /*Create a chart*/
    chart_more = lv_chart_create(lv_scr_act());
    lv_obj_set_size(chart_more, 200, 150);
    lv_obj_align(chart_more, LV_ALIGN_CENTER, -30, -30);
    lv_chart_set_range(chart_more, LV_CHART_AXIS_PRIMARY_Y, -1000, 1000);

    /*Do not display points on the data*/
    lv_obj_set_style_size(chart_more, 0, 0, LV_PART_INDICATOR);

    ser_tem_more = lv_chart_add_series(chart_more, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y);

    //uint32_t pcnt = sizeof(ecg_sample) / sizeof(ecg_sample[0]);
    lv_chart_set_point_count(chart_more, 1000);
    //lv_chart_set_ext_y_array(chart_more, ser, (lv_coord_t *)ecg_sample);

    lv_obj_t * slider;
    slider = lv_slider_create(lv_scr_act());
    lv_slider_set_range(slider, 256, 256 * 10);
    lv_obj_add_event_cb(slider, slider_x_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
    lv_obj_set_size(slider, 200, 10);
    lv_obj_align_to(slider, chart_more, LV_ALIGN_OUT_BOTTOM_MID, 0, 20);

    slider = lv_slider_create(lv_scr_act());
    lv_slider_set_range(slider, 256, 256 * 10);
    lv_obj_add_event_cb(slider, slider_y_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
    lv_obj_set_size(slider, 10, 150);
    lv_obj_align_to(slider, chart_more, LV_ALIGN_OUT_RIGHT_MID, 20, 0);
}